#version 330 core
out vec4 FragColor;
in vec3 FragPos;
in vec3 Normal;

// 材质结构
struct material_data
{
    float alpha;
    mat3x3 R;
};

// 光照结构
struct lighting_data
{
    vec3 color;
    vec3 pos;
    vec3 decrease;
};

uniform material_data Material;
uniform lighting_data Lighting;
uniform bool IfLighting;
uniform vec3 ViewerPos;

void main()
{
    if (IfLighting)
    {
        vec3 n = Normal;
        vec3 l = normalize(Lighting.pos - FragPos);
        vec3 v = normalize(ViewerPos - FragPos);

        // 计算光源距离，ad^2+bd+c 得到衰减因子
        float d = distance(FragPos, Lighting.pos);
        d = 1.0 / (Lighting.decrease.x * d * d + Lighting.decrease.y * d + Lighting.decrease.z);

        // 计算半角向量
        vec3 h = normalize(l + v);

        // 根据夹角计算衰减系数：注意先对夹角余弦取正，然后再作用指数 alpha
        float l_dot_n = max(dot(l, n), 0);
        float n_dot_h = pow(max(dot(n, h), 0), Material.alpha);

        FragColor.x = Material.R[0][0] * Lighting.color.x +
                (Material.R[0][1] * Lighting.color.x * l_dot_n +
                Material.R[0][2] * Lighting.color.x * n_dot_h) * d;
        FragColor.y = Material.R[1][0] * Lighting.color.y +
                (Material.R[1][1] * Lighting.color.y * l_dot_n +
                Material.R[1][2] * Lighting.color.y * n_dot_h) * d;
        FragColor.z = Material.R[2][0] * Lighting.color.z +
                (Material.R[2][1] * Lighting.color.z * l_dot_n +
                Material.R[2][2] * Lighting.color.z * n_dot_h) * d;

        // 防止颜色越界
        FragColor.x = min(max(FragColor.x, 0), 1);
        FragColor.y = min(max(FragColor.y, 0), 1);
        FragColor.z = min(max(FragColor.z, 0), 1);
        FragColor.w = 1;
    }
    else
    {
        FragColor = vec4(Lighting.color, 1.0);
    }
}
